﻿using System;
using System.Reflection;

namespace Demo
{
    class Program
    {
        /***
         * Type类的属性
            Name 数据类型名
            FullName 数据类型的完全限定名(包括命名空间名)
            Namespace 定义数据类型的命名空间名
            IsAbstract 指示该类型是否是抽象类型
            IsArray   指示该类型是否是数组
            IsClass   指示该类型是否是类
            IsEnum   指示该类型是否是枚举
            IsInterface    指示该类型是否是接口
            IsPublic 指示该类型是否是公有的
            IsSealed 指示该类型是否是密封类
            IsValueType 指示该类型是否是值类型
        Type类的方法
                GetConstructor(), GetConstructors()：返回ConstructorInfo类型，用于取得该类的构造函数的信息
                GetEvent(), GetEvents()：返回EventInfo类型，用于取得该类的事件的信息
                GetField(), GetFields()：返回FieldInfo类型，用于取得该类的字段（成员变量）的信息
                GetInterface(), GetInterfaces()：返回InterfaceInfo类型，用于取得该类实现的接口的信息
                GetMember(), GetMembers()：返回MemberInfo类型，用于取得该类的所有成员的信息
                GetMethod(), GetMethods()：返回MethodInfo类型，用于取得该类的方法的信息
                GetProperty(), GetProperties()：返回PropertyInfo类型，用于取得该类的属性的信息
            可以调用这些成员，其方式是调用Type的InvokeMember()方法，或者调用MethodInfo, PropertyInfo和其他类的Invoke()方法。 
         * 
         * ***/

        static void Main(string[] args)
        {

            #region 反射获取类型
            //获取给定类型的Type
            Type t = typeof(string);
            string s = "grayworm";
            Type t2 = s.GetType();
            Type t3 = Type.GetType("System.String");

            //查看结构
            string n = "grayworm";
            Type t4 = n.GetType();
            // 遍历type方法
            //foreach (MemberInfo mi in t.GetMembers())
            //{
            //    Console.WriteLine("{0}/t{1}", mi.MemberType, mi.Name);
            //}

            var a = new A("jet");
            var ty = a.GetType();
            #endregion

            #region 获取构造函数
            Console.WriteLine("=======获取构造函数========");
            //获取构造函数
            foreach (var item in ty.GetConstructors())
            {
                Console.Write(item.Name + "-----");
                //获取构造函数的参数
                foreach (var pi in item.GetParameters())
                {
                    Console.Write(pi.ParameterType.ToString() + " --" + pi.Name + "|");
                }

            }
            #endregion

            #region 用构造函数创建对象
            Console.WriteLine("=========用有参构造函数创建对象===========");

            Type ty1 = typeof(A);
            Type[] pt = new Type[1];
            pt[0] = typeof(string);
          
            //根据参数类型获取构造函数 
            ConstructorInfo ci = ty1.GetConstructor(pt);
            if (ci != null)
            {
                Console.WriteLine($"对象是{ci.ToString()}");
            }
            object o = ci.Invoke(new object[] {"jet" });

            A a1 = o as A;
            a1.Say();

            Console.WriteLine("=======用无惨构造函数创建对象============");

            Type ty2 = typeof(A);
         

            //根据参数类型获取构造函数 
            ConstructorInfo ci2 = ty2.GetConstructor(new Type[0]);
            if (ci2 != null)
            {
                Console.WriteLine($"无惨构造函数创建的对象是{ci2.ToString()}");
            }
            object o2 = ci2.Invoke(new object[] {  });

            A a12 = o2 as A;
            a12.Say();

            #endregion

            #region 用Activator生成对象
            Console.WriteLine("=========用Activator生成对象===============");
            Type t5 = typeof(A);
            //用Activator的CreateInstance静态方法，生成新对象 
            object o5 = Activator.CreateInstance(t5, "jet", 45);
            A a5 = o5 as A;
            a5.Say();

            #endregion

            #region 获取属性  方法 字段
            Console.WriteLine("============获取属性=================");
            A nc = new A();
            Type t6 = nc.GetType();
            PropertyInfo[] pis6 = t6.GetProperties();
            foreach (PropertyInfo pi6 in pis6)
            {
                Console.WriteLine(pi6.Name);
            }

            Console.WriteLine("============获取方法=================");
            A a7 = new A();
            Type t7 = nc.GetType();
            MethodInfo[] pis7 = t7.GetMethods();
            foreach (var pi7 in pis7)
            {
                Console.WriteLine(pi7.Name);
            }

            Console.WriteLine("============获取字段=================");
            A a8 = new A();
            Type t8 = nc.GetType();
            FieldInfo[] pis8 = t8.GetFields();
            foreach (var pi8 in pis8)
            {
                Console.WriteLine(pi8.Name);
            }
            #endregion

            #region 反射调用方法 设置字段属性
            Console.WriteLine("==============反射调用方法设置字段属性=================");
            Type t9 = new A().GetType();
            object obj = Activator.CreateInstance(t9);
            //取得ID字段 
            FieldInfo fi = t9.GetField("EN");

            Console.WriteLine("字段的值" + fi.Name);
            //给ID字段赋值 
            // fi.SetValue(obj, 21);
            //取得MyName属性 
            PropertyInfo pi1 = t9.GetProperty("Name");
            //给MyName属性赋值 
            pi1.SetValue(obj, "jess", null);

            //取得show方法 
            MethodInfo mi = t9.GetMethod("Say");
            //调用show方法 
            mi.Invoke(obj, null);

            MethodInfo mi2 = t9.GetMethod("Show");
            //调用show方法 
            mi2.Invoke(obj, new object[] { "傻吊" });
            #endregion


            #region 通过dll 获取 方法字段等
            // 环形集合dll

            Assembly assembly = Assembly.LoadFrom("../../../ZL.HRS.ApiDto.dll");
            Type[] aa = assembly.GetTypes();
            foreach (Type t10 in aa)
            {
                if (t10.FullName == "ZL.HRS.ApiDto.ViewModel.LoginInput")
                {
                    object o10 = Activator.CreateInstance(t10);
                }
            }



            #endregion



        }
    }


    public abstract class B {
        static B()
        {
            Console.WriteLine("B静态构造函数");
        }
        public B()
        {
            Obj = Guid.NewGuid();
        }
        public Guid Obj { get; set; }
    }



    public class A:B
    {
        public int Id { get; set; }
        public string Name { get; set; }

        private string p { get; set; }

        public A()
        {

        }
        public const string EN = "HK";

        public A(string name)
        {
            Name = name;
        }
        public A(string name,int id)
        {
            Name = name;
            Id = id;
        }



        public void Say()
        {
            Console.WriteLine(Name);
        }

        public void Show(string name)
        {
            Console.WriteLine($"调用了show方法({name})");
        }


    }

}
